package relu.fbs.jfm;

import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;

import jfm.model.Types.CropType;
import relu.fbs.BadDataException;
import relu.fbs.DataValue;
import relu.fbs.jfm.JFMFarmData.JFMFarmDatum;
import relu.fbs.FarmData;

public abstract class AbstractJFMFarmData extends FarmData {

	protected final Map<JFMFarmDatum,DataValue> farmData = new LinkedHashMap<JFMFarmDatum,DataValue>();
	protected final Map<CropType,AbstractJFMCropData> crops = new LinkedHashMap<CropType,AbstractJFMCropData>();
	public final int farmId;
	
	public double getFarmDatum(JFMFarmDatum dt){
		if ( farmData.containsKey(dt)){
			return farmData.get(dt).autoValue();
		} else {
			throw new Error("Attempt to get undefined datum "+dt);
		}
	}
	
	public AbstractJFMFarmData(int fi){
		farmId=fi;
	}
	public Map<CropType,AbstractJFMCropData> crops(){
		return Collections.unmodifiableMap(crops);
	}

	public static String allToCSVHeader(){
		StringBuffer buff=new StringBuffer();
		for ( JFMFarmDatum nm:JFMFarmDatum.values()){
			buff.append(nm.RName+",");
		}
		for ( CropType ct:FarmData.jfmCropTypesMap.keySet()){
			buff.append(JFMCropData.allToCSVCropLabels(ct));
			buff.append(",");
		}
		for ( CropType ct:FarmData.jfmSetAsideCrops.values()){
			buff.append(JFMCropData.allToCSVCropLabels(ct));
			buff.append(",");
		}
		buff.append(JFMCropData.allToCSVCropLabels(CropType.SETASIDE));
		buff.append(",");
		buff.deleteCharAt(buff.length()-1); // Delete last comma
		buff.append("\n");
		return buff.toString();
	}
	

	public String writeAllToCSV() throws BadDataException {
		StringBuffer buff = new StringBuffer();
		DecimalFormat fmt = new DecimalFormat("#00.00");
		for ( JFMFarmDatum nm:JFMFarmDatum.values()){
			if ( farmData.containsKey(nm)){
				buff.append(fmt.format(farmData.get(nm).autoValue())+",");
			} else {
				buff.append(0.0+",");
			}
		}
		int i=0;
		for ( AbstractJFMCropData cdata: crops.values()){
			buff.append(cdata.allToCSV(fmt));
			i++;
			if ( i < crops.size()){
				buff.append(",");
			}
		}
		
		buff.append("\n");
		return buff.toString();
	}
	
	public void writeAllToCSV(FileWriter writer) throws IOException, BadDataException {
		writer.write(writeAllToCSV());
		writer.flush();
	}
	
	public String toString() {
		StringBuffer buff=new StringBuffer();

		DecimalFormat fmt = new DecimalFormat("#00.00");
		for ( JFMFarmDatum nm:JFMFarmDatum.values()){
			if ( farmData.containsKey(nm)){
				buff.append(nm+": "+fmt.format(farmData.get(nm).autoValue())+"\n");
			}
		}
		buff.append(JFMCropData.allToCSVCropLabels()+"\n");
		for ( AbstractJFMCropData cdata: crops.values()){
			buff.append(cdata.cropType+": "+cdata.allToCSV(fmt)+"\n");
		}			
		buff.append("\n");
	
		return buff.toString();
	}
	
}
